package org.jeecg.modules.api.controller;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.exception.IllegalPayOrderException;
import org.jeecg.common.exception.QrCodeGenerateException;
import org.jeecg.modules.api.factory.OrderFactory;
import org.jeecg.modules.api.service.*;
import org.jeecg.modules.api.util.SignUtils;
import org.jeecg.modules.api.vo.*;
import org.jeecg.modules.equipment.entity.Equipment;
import org.jeecg.modules.equipment.service.IEquipmentService;
import org.jeecg.modules.equipmentbind.service.IEquipmentBindService;
import org.jeecg.modules.merchant.entity.Merchant;
import org.jeecg.modules.merchant.service.IMerchantService;
import org.jeecg.modules.order.entity.Order;
import org.jeecg.modules.order.service.IOrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.Date;
import java.util.UUID;

/**
 * @author: Dean
 * @since: 2019/9/28
 */
@Slf4j
@Api(tags = "order api")
@RestController
@RequestMapping("/api")
public class ApiController {
    @Autowired
    private IOrderService iOrderService;

    @Autowired
    private TspRemoteService tspRemoteService;

    @Autowired
    private OrderFactory orderFactory;

    @Autowired
    private IEquipmentService iEquipmentService;

    @Autowired
    private IMerchantService iMerchantService;

    @PostMapping("/order/create")
    @ApiOperation("创建订单接口")
    public Result<OrderQueryResponse> create(@RequestBody @Validated CreateOrderForm createOrderForm) {
        log.info("创建订单，参数为[{}]", createOrderForm.toString());
        SignUtils.checkSign(createOrderForm);
        Equipment equipment = iEquipmentService.findByCode(createOrderForm.getDevice_no());
        Order order = orderFactory.toOrderEntity(createOrderForm, equipment);
        iOrderService.save(order);
        TspOrderResponse tspOrderResponse = tspRemoteService.createOrder(order);
        if (tspOrderResponse.getSuccess()) {
            order.setStatus(0);
            order.setPosTradeNo(tspOrderResponse.getData().getPayOrderNo());
        } else {
            order.setStatus(9);
        }
        iOrderService.updateById(order);
        OrderQueryResponse response = OrderQueryResponse.builder()
                .pp_trade_no(order.getPosTradeNo())
                .total_fee(createOrderForm.getTotal_fee())
                .time_end(order.getCreateTime())
                .build();
        return Result.ok(response);
    }

    @PostMapping("/order/query")
    @ApiOperation("订单查询接口")
    @ApiResponses({
            @ApiResponse(code = 201,message = "IN PAYMENT",reference="")
    })
    public Result<OrderQueryResponse> query(@RequestBody @Validated OrderQuery orderQuery) {
        //SignUtils.checkSign(orderQuery);
        Equipment equipment = iEquipmentService.findByCode(orderQuery.getDevice_no());
        Order order = iOrderService.findOrderByPayOrderNo(orderQuery.getPp_trade_no());
        TspOrderStatusResponse tspOrderStatusResponse =
                tspRemoteService.getOrderStatus(orderQuery.getPp_trade_no());
        if (!tspOrderStatusResponse.getSuccess() || tspOrderStatusResponse.getData() == null
                || tspOrderStatusResponse.getData().getStatus() == null) {
            throw new IllegalPayOrderException(tspOrderStatusResponse.getMessage());
        }
        String status = tspOrderStatusResponse.getData().getStatus();
        Integer code = null;
        if (status.equals("0")) {
            code = 201;
        } else if (status.equals("1")) {
            code = 200;
            order.setStatus(1);
            order.setPayDate(tspOrderStatusResponse.getData().getPayTime());
            iOrderService.updateById(order);
        } else {
            code = 300;
            order.setStatus(2);
            iOrderService.updateById(order);
        }
        OrderQueryResponse response = OrderQueryResponse.builder()
                .pp_trade_no(order.getPosTradeNo())
                .total_fee(order.getAmount())
                .time_end(order.getCreateTime())
                .build();
        return Result.okCustom(response, code);
    }

    @PostMapping("/order/qrcode")
    @ApiOperation("支付码生成接口")
    public Result<QrCodeResponse> qrcode(@RequestBody @Validated QrCodeForm qrCodeForm) {
        //SignUtils.checkSign(qrCodeForm);
        log.info("支付码生成请求{}", qrCodeForm.toString());
        Equipment equipment = iEquipmentService.findByCode(qrCodeForm.getDevice_no());
        Order order = iOrderService.findOrderByPayOrderNo(qrCodeForm.getPp_trade_no());
        TspCollectCodeResponse tspCollectCodeResponse = tspRemoteService.collectCodeGenerate(qrCodeForm.getPp_trade_no());
        if (!tspCollectCodeResponse.getSuccess()) {
            throw new QrCodeGenerateException("generation error!");
        }
        QrCodeResponse response = QrCodeResponse.builder()
                .pp_trade_no(order.getPosTradeNo())
                .qr_text(tspCollectCodeResponse.getCollectCode())
                .total_fee(order.getAmount())
                .time_end(order.getCreateTime())
                .build();
        return Result.ok(response);
    }

    @PostMapping("/order/collect")
    @ApiOperation("扫码收款接口")
    public Result<CollectResponse> collect(@RequestBody @Validated CollectForm collectForm) {
        //SignUtils.checkSign(collectForm);
        Equipment equipment = iEquipmentService.findByCode(collectForm.getDevice_no());
        Order order = iOrderService.findOrderByPayOrderNo(collectForm.getPp_trade_no());
        TspCompleteOrderResponse tspCompleteOrderResponse =
                tspRemoteService.completeOrder(collectForm.getPp_trade_no(), collectForm.getQr_text());
        if (!tspCompleteOrderResponse.getSuccess()) {
            throw new IllegalPayOrderException(tspCompleteOrderResponse.getMessage());
        }
        order.setStatus(1);
        order.setPayDate(tspCompleteOrderResponse.getData().getPayTime());
        iOrderService.updateById(order);
        CollectResponse response = CollectResponse.builder()
                .pp_trade_no(order.getPosTradeNo())
                .total_fee(order.getAmount())
                .time_end(order.getCreateTime())
                .build();
        return Result.ok(response);
    }

    @PostMapping("/device/poi/query")
    @ApiOperation("poi门店信息获取")
    public Result<PoiQueryResponse> poiInfo(@RequestBody @Validated PoiQuery poiQuery) {
        //SignUtils.checkSign(poiQuery);
        Equipment equipment = iEquipmentService.findByCode(poiQuery.getDevice_no());
        Merchant merchant = iMerchantService.getById(equipment.getMerchantId());
        PoiQueryResponse response = PoiQueryResponse.builder()
                .poi_address(merchant.getAddress())
                .poi_id(merchant.getCode())
                .poi_name(merchant.getName())
                .build();
        return Result.ok(response);
    }

    @RequestMapping("/callback")
    public void callback(HttpServletRequest request) throws IOException {
        log.info("callback{}", request.getRequestURL());
        String orderNo = request.getParameter("orderNo");
        Order order = iOrderService.findOrderByOrderNo(orderNo);
        if (order != null) {
            TspOrderStatusResponse tspOrderStatusResponse = tspRemoteService.getOrderStatus(order.getPosTradeNo());
            if (tspOrderStatusResponse.getSuccess() || tspOrderStatusResponse.getData() == null
                    || tspOrderStatusResponse.getData().getStatus() == null) {
                throw new IllegalPayOrderException(tspOrderStatusResponse.getMessage());
            }
            String status = tspOrderStatusResponse.getData().getStatus();
            Integer code = null;
            if (status.equals("0")) {
                code = 201;
            } else if (status.equals("1")) {
                code = 200;
                order.setStatus(1);
                order.setPayDate(tspOrderStatusResponse.getData().getPayTime());
                iOrderService.updateById(order);
            } else {
                code = 300;
                order.setStatus(2);
                iOrderService.updateById(order);
            }
        }
        BufferedReader br = request.getReader();
        String str = "";
        String listString = "";
        while ((str = br.readLine()) != null) {
            listString += str;
        }
        log.info("callback body{}", listString);
    }
}
